home *** CD-ROM | disk | FTP | other *** search
- /*________________________________________________________________________________
- DebugLeaks.c: leaks tracking code.
-
- Note:
- The routines provided here are only shells to guide you in implementing leaks
- code. No implementation is provided. However, suggested data structures are
- shown.
- ________________________________________________________________________________*/
-
- #include "DebugLeaks.h"
- #include "DebugTrapsOff.h"
-
-
- #if USE_DEBUG_LEAKS // [
-
-
- /*________________________________________________________________________________
- Suggested struct to remember an item.
- ________________________________________________________________________________*/
- typedef struct RememberedItem
- {
- const void *itemMemory; // Ptr, Handle, or object pointer
-
- // if it's an object, the file name isn't useful, since allocation always occurs
- // in operator new. So store the object size instead, since we cannot obtain that later.
- #define kMaxObjectSize ( 65535 ) // max size we can remember in 'objectSize' field
- union
- {
- UInt16 fileNameIndex; // index into a string list
- UInt16 objectSize; // if an object
- } info;
-
- DebugLeaksHowAllocated howAllocated;
-
- UInt8 notReallyALeak : 1; // used to ignore known leaks
- UInt8 objectSizeMoreThanMax : 1; // if an object: it's size exceeds kMaxObjectSize
- UInt8 addedWhileSuspended : 1; // used to ignore items we want to ignore
- UInt8 unused : 5;
- } RememberedItem;
-
- #define ItemFileNameIndex( i ) ( (i)->info.fileNameIndex )
- #define ItemObjectSize( i ) ( (i)->info.objectSize )
- #define ItemIsObject( i ) ( (i)->howAllocated == kSDL_OperatorNew )
-
-
-
- /*________________________________________________________________________________
- Suggested struct for a Leaks session.
-
- Contains an array of RememberItems and associated information
- ________________________________________________________________________________*/
- typedef struct LeaksSession
- {
- Str32 sessionName;
-
- UInt32 maxItems; // e.g. items = NewHandle( maxItems * sizeof( **items ) );
- RememberedItem **items; // Handle to array of RememberedItems
- UInt32 numActiveItems; // how many are actually in use right now [0, numActiveItems -1]
-
- // counts how many of each are allocated; increases only
- // could be useful for analyzing program memory allocations
- UInt32 numHandles;
- UInt32 numPtrs;
- UInt32 numObjects;
- } LeaksSession;
-
-
-
- /*________________________________________________________________________________
- Suggested struct for keeping a list of file names
- ________________________________________________________________________________*/
- typedef struct StringList
- {
- UInt16 numStrings;
- unsigned char strings[]; // packed array of pascal strings follows, just like a STR#
- } StringList, **StringListHandle;
-
-
- /*________________________________________________________________________________
- Suggested struct for the Leaks manager.
-
- Remembers all sessions as a stack; top one is current session.
- ________________________________________________________________________________*/
- typedef struct SessionList
- {
- UInt16 numSessions; // how many sessions currently exist
- UInt16 maxSessions; // maximum number of sessions possible
-
- UInt16 suspendCount; // to track suspend/resume pairing
-
- #define kDefaultNameStrIndex 1 // we add one default string when we create it
- StringListHandle fileNameList;
-
- LeaksSession sessionsArray[ ]; // dynamically allocate as many as desired
- } SessionList;
-
-
-
-
- /*————————————————————————————————————————————————————————————————————————————————————————
- Note:
- Some of the routines in this file would normally be called only from DebugTraps,
- usually not from general program code.
- ————————————————————————————————————————————————————————————————————————————————————————*/
-
- #if PRAGMA_MARK_SUPPORTED
- #pragma mark --- Rare Public Use ---
- #endif
-
-
- /*————————————————————————————————————————————————————————————————————————————————————————
- Remember a Ptr or Handle.
-
- Use the next available slot in the list.
-
- Note: A RememberedItem may need to initialized slightly differently for an object
- so handle that in DebugLeaks_RememberObject, not here.
- ————————————————————————————————————————————————————————————————————————————————————————*/
- static void
- RememberHandleOrPtr(
- const void * theItem,
- DebugLeaksHowAllocated howAllocated,
- const char * srcFileNameCString)
- {
- }
-
-
-
- /*————————————————————————————————————————————————————————————————————————————————————————
- Forget an item; it has been disposed of properly.
-
- Copy the last in-use item to its place to keep the list compact.
- ————————————————————————————————————————————————————————————————————————————————————————*/
- static void
- ForgetItem( const void *handleOrPtr)
- {
- }
-
-
- /*————————————————————————————————————————————————————————————————————————————————————————
- A Handle has been allocated. Remember it.
- ————————————————————————————————————————————————————————————————————————————————————————*/
- void
- DebugLeaks_RememberHandle(
- Handle theHandle,
- DebugLeaksHowAllocated howAllocated,
- const char * srcFileNameCString)
- {
- RememberHandleOrPtr( theHandle, howAllocated, srcFileNameCString);
- }
-
-
-
- /*————————————————————————————————————————————————————————————————————————————————————————
- A Handle has been deallocated. Forget it.
- ————————————————————————————————————————————————————————————————————————————————————————*/
- void
- DebugLeaks_ForgetHandle( Handle theHandle)
- {
- ForgetItem( theHandle );
- }
-
-
-
- /*————————————————————————————————————————————————————————————————————————————————————————
- A memory manager 'Ptr' has been allocated. Remember it.
- ————————————————————————————————————————————————————————————————————————————————————————*/
- void
- DebugLeaks_RememberPtr(
- void * thePtr,
- DebugLeaksHowAllocated howAllocated,
- const char * srcFileNameCString)
- {
- RememberHandleOrPtr( thePtr, howAllocated, srcFileNameCString);
- }
-
-
- /*————————————————————————————————————————————————————————————————————————————————————————
- A Ptr has been deallocated. Forget it.
- ————————————————————————————————————————————————————————————————————————————————————————*/
- void
- DebugLeaks_ForgetPtr( void *thePtr)
- {
- ForgetItem( thePtr );
- }
-
-
-
- /*————————————————————————————————————————————————————————————————————————————————————————
- A AEDesc has been allocated. Remember it.
- ————————————————————————————————————————————————————————————————————————————————————————*/
- void
- DebugLeaks_RememberAEDesc(
- AEDesc * theAEDesc,
- DebugLeaksHowAllocated howAllocated,
- const char * srcFileNameCString)
- {
- AssertAddressIsValidAlign2( theAEDesc, "\pDebugLeaks_RememberAEDesc");
-
- if ( theAEDesc->descriptorType != typeNull &&
- IsntNil( theAEDesc->dataHandle ))
- {
- RememberHandleOrPtr( theAEDesc->dataHandle, howAllocated, srcFileNameCString);
- }
- }
-
-
-
- /*————————————————————————————————————————————————————————————————————————————————————————
- A AEDesc has been deallocated. Forget it.
- ————————————————————————————————————————————————————————————————————————————————————————*/
- void
- DebugLeaks_ForgetAEDesc( AEDesc *theAEDesc)
- {
- AssertAddressIsValidAlign2( theAEDesc, "\pDebugLeaks_ForgetAEDesc");
-
- if ( theAEDesc->descriptorType != typeNull &&
- IsntNil( theAEDesc->dataHandle ) &&
- DebugLeaks_ItemIsRemembered( theAEDesc->dataHandle ))
- {
- ForgetItem( theAEDesc->dataHandle );
- }
- }
-
-
-
- /*————————————————————————————————————————————————————————————————————————————————————————
- An object has been allocated. Remember it.
-
- Override operator new() so you can remember objects.
- ————————————————————————————————————————————————————————————————————————————————————————*/
- void
- DebugLeaks_RememberObject(
- void *object,
- UInt32 size)
- {
- // initialize a RememberedItem appropriately and add it to list
- }
-
-
- /*————————————————————————————————————————————————————————————————————————————————————————
- An object has been deallocated. Forget it.
-
- Note: you will need to override operator delete() so you can call this routine.
- ————————————————————————————————————————————————————————————————————————————————————————*/
- void
- DebugLeaks_ForgetObject( void *object )
- {
- ForgetItem( object );
- }
-
-
-
- /*————————————————————————————————————————————————————————————————————————————————————————
- Return true if an item is remembered.
- ————————————————————————————————————————————————————————————————————————————————————————*/
- Boolean
- DebugLeaks_ItemIsRemembered( const void *handleOrPtr )
- {
- return( false );
- }
-
-
- /*————————————————————————————————————————————————————————————————————————————————————————
- A Handle is being disposed of via DisposeHandle().
- Verify this is the proper way to dispose of it, as opposed to a more specific routine.
-
- For example, DisposeHandle should not be called on an IconSuiteHandle.
- ————————————————————————————————————————————————————————————————————————————————————————*/
- void
- DebugLeaks_DisposingHandle( Handle theHandle)
- {
- }
-
-
-
- /*————————————————————————————————————————————————————————————————————————————————————————
- A Ptr is being disposed of via DisposePtr().
- Verify this is the proper way to dispose of it, as opposed to a more specific routine.
-
- For example, DisposePtr should not be called on a WindowPtr.
- ————————————————————————————————————————————————————————————————————————————————————————*/
- void
- DebugLeaks_DisposingPtr( Ptr thePtr)
- {
- }
-
-
-
- /*————————————————————————————————————————————————————————————————————————————————————————
- Ignore this item (Ptr, Handle or object). It will not be reported as a leak.
- However, the item should remain in the list of remembered items until it has
- been disposed. This allows stricter assertions in some cases (e.g. an attempt to
- dispose of it twice).
- ————————————————————————————————————————————————————————————————————————————————————————*/
- void
- DebugLeaks_IgnoreItem( const void *mem)
- {
- }
-
-
-
- #if PRAGMA_MARK_SUPPORTED
- #pragma mark -
- #pragma mark --- General Public Use ---
- #endif
-
-
- /*————————————————————————————————————————————————————————————————————————————————————————
- Initialize the leaks code. Call this before using any leaks routines.
-
- Calls to Leaks services before initialization are ignored.
- ————————————————————————————————————————————————————————————————————————————————————————*/
- void
- DebugLeaks_Init(void)
- {
- }
-
-
-
- /*————————————————————————————————————————————————————————————————————————————————————————
- After calling this calls to Leaks services are ignored.
- ————————————————————————————————————————————————————————————————————————————————————————*/
- void
- DebugLeaks_Dispose(void)
- {
- }
-
-
- /*————————————————————————————————————————————————————————————————————————————————————————
- Allocate memory for a new session and make it the current session.
- ————————————————————————————————————————————————————————————————————————————————————————*/
- void
- DebugLeaks_StartSession(
- UInt32 maxItemsToTrack,
- ConstStr255Param sessionName)
- {
- }
-
-
- /*————————————————————————————————————————————————————————————————————————————————————————
- Stop remembering leaks, and if there are any leaks, report them. Then dispose
- of the session. The previous session (if any) becomes active.
- ————————————————————————————————————————————————————————————————————————————————————————*/
- void
- DebugLeaks_StopSession(void)
- {
- }
-
-
- /*————————————————————————————————————————————————————————————————————————————————————————
- All subsequent allocations are recorded, but are marked as having occured during
- a suspended session so they won't be considered leaks. If we completely ignored them,
- then we would get complaints later from DebugLeaks_ForgetXXX() routines.
-
- Keep a "suspend counter" which is decremented for each resume call.
- ————————————————————————————————————————————————————————————————————————————————————————*/
- void
- DebugLeaks_SuspendSession( void )
- {
- }
-
-
- /*————————————————————————————————————————————————————————————————————————————————————————
- Back to normal (provided the suspend count becomes 0).
- ————————————————————————————————————————————————————————————————————————————————————————*/
- void
- DebugLeaks_ResumeSession( void )
- {
- }
-
-
-
-
-
-
- #endif // ] USE_DEBUG_LEAKS
-
-
-
-
-
-
-
-
-